﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once

#include <vector>
#include "IIfcObject.h"
#include "OwnerPtr.h"
#include "WeakReferenceable.h"

namespace gcmp
{
    class IIfcBuildingModel;

    /// \brief IFC普通实体对象, 不包括字符型，枚举型，整数型和浮点型对象，一般带有属性
    class GCMP_IFC_INTERFACE_EXPORT IIfcEntity : public IIfcObject, public WeakReferenceable
    {
        DEFINE_CAST_DERIVED(gcmp::IIfcEntity, gcmp::IIfcObject);
    public:
        /// \brief 对IFC普通实体类对象克隆。
        /// \return 返回克隆后的IFC普通实体对象指针
        virtual OwnerPtr<IIfcEntity> Clone() const = 0;

        /// \brief 析构函数
        virtual ~IIfcEntity() {}

        /// \brief 获取该IFC对象的属性个数。
        /// \return 返回该IFC对象的属性个数
        ///可以在设置本对象属性时查询使用
        virtual size_t GetAttributesNumber() const = 0;

        /// \brief 获取该IFC对象所有属性的类型名。
        /// \return 返回当前IFC对象的所有类型名
        virtual std::vector<std::string> GetExplicitAttributesNames() const = 0;

        /// \brief 获取该IFC对象的类名。
        /// \return 返回该IFC对象的类名引用
        ///注意：返回的类名是IFC三方库中导出的类名，都是大写字符
        virtual const std::wstring& GetIfcClassName() const = 0;

        /// \brief 设置本对象的属性值。
        /// \param attributeObjects 要设置的属性值集合
        /// \param pHintInfos 返回属性设置完成之后的属性名称和值的信息
        /// \return 返回设置属性状态和对象属性设置完之后各属性对应的名称和值，设置成功返回true, 否则返回false
        ///注意：传入的attributeObjects的容器的大小需要和对象的属性值数目一致，也就是接口GetAttributesNumber()返回的值一致
        ///对于IIfcEntity对象作为属性时，需要确保在传入SetAttributes之前该IIfcEntity对象已被加入到buildingModel中，否则该属性会设置失败
        ///pHintInfos传入有效指针时，会返回属性设置完成之后的属性名称和值的信息，可用于调用后对入参传入顺序的校验，如果不传入有效指针，则不返回任何信息。
        virtual bool SetAttributes(const std::vector<const IIfcObject*>& attributeObjects, std::vector<std::pair<std::string, std::wstring>>* pHintInfos) = 0;

        /// \brief 获取本实体对象在BuildingModel中的entityId.
        /// \return 返回本实体对象在BuildingModel中的entityId，若加入BuildingModel失败，则返回值为-1.
        ///每一个Entity实体对象在一个BuildingModel中的entityId是唯一的。
        virtual int GetIfcEntityId() const = 0;

        /// \brief 通过属性名和IIfcObject对象来设置属性
        /// \param name 属性名
        /// \param pIfcObject 对应的Ifc对象
        /// \return 设置成功返回true，否则返回false
        virtual bool SetAttribute(const std::string& name, const IIfcObject* pIfcObject) = 0;

        /// \brief 通过属性名获取对应的Ifc对象
        /// \param attributeName 属性名
        /// \return 对应的Ifc对象指针
        virtual OwnerPtr<IIfcObject> GetAttribute(const std::string& attributeName) const = 0;
    };
}
